package com.kob.botrunningsystem.Service.impl.utils;

import com.kob.botrunningsystem.utils.BotInterface;
import org.joor.Reflect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.UUID;
import java.util.function.Supplier;

/**
 * @author molimark<br />
 * @date: 2023/4/3 16:16<br/>
 * @description: <br/>
 */

@Component
public class Consumer extends Thread{
    private Bot bot;
    private static RestTemplate restTemplate;
    private final static String receiveBotMoveUrl = "http://127.0.0.1:3000/pk/receive/bot/move/";

    @Autowired
    public void setRestTemplate(RestTemplate restTemplate){Consumer.restTemplate = restTemplate;}

    public void startTimeout(long timeout, Bot bot){
        this.bot = bot;
        this.start();

        try {
            // 最多等待timeout秒,防止用户程序死循环，所以要调用start()开一个新线程执行代码编译运行
            this.join(timeout);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            this.interrupt(); // 中断当前线程
        }
    }

    private String addUid(String code,String uid){ // 在code中的Bot类名后添加uid
        int k = code.indexOf(" implements java.util.function.Supplier<Integer>");
        return code.substring(0,k) + uid + code.substring(k);
    }

    @Override
    public void run() {
        UUID uuid = UUID.randomUUID();
        String uid = uuid.toString().substring(0,8);

        // 如果name相同的话代码只会编译一次，而不同用户的代码是不一样的，所以name不能相同，加上个uid
        // BotCode必须实现BotInterface接口

        Supplier<Integer> botInterface = Reflect.compile(
                "com.kob.botrunningsystem.utils.AIBot" + uid,
                addUid(bot.getBotCode(),uid)
        ).create().get();

        File file = new File("input.txt");
        //Java7新特性，try括号内的资源会在try语句结束后自动释放，前提是这些可关闭资源必须实现java.lang.AutoCloseable接口
        try(PrintWriter fout = new PrintWriter(file)) {
            fout.println(bot.getInput());
            fout.flush();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }

        // 调用编译后的代码并得到结果
        Integer direction = botInterface.get();

        MultiValueMap<String,String> data = new LinkedMultiValueMap<>();
        data.add("user_id",bot.getUserId().toString());
        data.add("direction",direction.toString());

        restTemplate.postForObject(receiveBotMoveUrl,data,String.class);
    }
}
